package com.paradogs.framework.core.utils;

import com.baidu.bjf.remoting.protobuf.Codec;
import com.baidu.bjf.remoting.protobuf.ProtobufProxy;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: yumi
 * @date: 2023/8/1  13:48
 * @Description: TODO
 */
public class ProtoUtils {

    /**
     * 优化效率，避免每次都创建一个编解码器，享元模式？
     * !! jprotobuf encode() 源码内部自带了缓存，所以其实不需要自己缓存了，
     * 可以直接 ProtobufProxy.create(clz).encode()
     */
    public static Map<Class<?>, Codec> codecMap = new ConcurrentHashMap<>();

    /**
     * jprotobuf 编码
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> byte[] encode(T obj) {

        if (obj == null) {
            return new byte[0];
        }

        if (!codecMap.containsKey(obj.getClass())) {
            codecMap.put(obj.getClass(), ProtobufProxy.create(obj.getClass()));
        }

        try {
            Codec codec = codecMap.get(obj.getClass());
            return codec.encode(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

    /**
     * jprotobuf 解码
     * @param bytes
     * @param clz
     * @param <T>
     * @return
     */
    public static <T> T decode(byte[] bytes, Class<T> clz) {

        if (byte[].class.isAssignableFrom(clz)) {
            return (T) bytes;
        }

        if (!codecMap.containsKey(clz)) {
            codecMap.put(clz, ProtobufProxy.create(clz));
        }
        try {
            return (T) codecMap.get(clz).decode(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
